

%include <std_string.i>
%import StdAlloc.i
%import StdIos.i

namespace std {
    %typemap(ctype) basic_string<char>, const basic_string<char>& "const char *"
    %typemap(imtype) basic_string<char>, const basic_string<char>& "string"
    %typemap(cstype) basic_string<char>, const basic_string<char>& "string"
    %typemap(csdirectorin) basic_string<char>, const basic_string<char>& "$iminput"
    %typemap(csdirectorout) basic_string<char>, const basic_string<char>& "$cscall"

    %typemap(in, canthrow=1) basic_string<char> %{ 
        if (!$input) { 
            SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "null string", 0); 
            return $null; 
        }
        $1.assign($input); %}
    %typemap(out) basic_string<char> %{ $result = SWIG_csharp_string_callback($1.c_str()); %}

    %typemap(directorout, canthrow=1) basic_string<char> %{ 
        if (!$input) { 
            SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "null string", 0); 
            return $null; 
            }
        $result.assign($input); 
    %}
    %typemap(directorin) basic_string<char> %{ $input = $1.c_str(); %}

    %typemap(csin) string "$csinput"
    %typemap(csout, excode=SWIGEXCODE) basic_string<char> {
        string ret = $imcall;$excode
        return ret;
    }
    %typemap(typecheck) string = char *;
    %typemap(throws, canthrow=1) basic_string<char> %{ 
        SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, $1.c_str());
        return $null; 
    %}

    %typemap(in, canthrow=1) const basic_string<char>& %{ 
        if (!$input) {
            SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "null string", 0);
            return $null;
        }
        $*1_ltype $1_str($input);
        $1 = &$1_str; 
    %}
    %typemap(out) const basic_string<char>& %{ $result = SWIG_csharp_string_callback($1->c_str()); %}

    %typemap(csin) const basic_string<char>& "$csinput"
    %typemap(csout, excode=SWIGEXCODE) const basic_string<char>& {
        string ret = $imcall;$excode
        return ret;
    }

    %typemap(directorout, canthrow=1, warning=SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG) const basic_string<char>& %{ 
        if (!$input) {
            SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "null string", 0);
            return $null;
        }
        static $*1_ltype $1_str;
        $1_str = $input;
        $result = &$1_str; 
    %}  
    %typemap(directorin) const basic_string<char>& %{ $input = $1.c_str(); %}

    %typemap(csvarin, excode=SWIGEXCODE2) const basic_string<char>& %{ 
        set { 
            $imcall;$excode 
        } 
    %}
    %typemap(csvarout, excode=SWIGEXCODE2) const basic_string<char>& %{ 
        get { 
            string ret = $imcall;$excode 
            return ret; 
        } 
    %}
    %typemap(typecheck) const basic_string<char>& = char *;
    %typemap(throws, canthrow=1) const basic_string<char>& %{ 
        SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, $1.c_str()); 
        return $null; 
   %}
}

namespace std {
    template <class _CharT, class _Traits = char_traits<_CharT>, typename _Alloc = allocator<_CharT>>
    class basic_string {
        public:
            typedef size_t size_type;    
            typedef ptrdiff_t difference_type;
            typedef _CharT value_type;
            typedef value_type reference;
            typedef value_type const_reference;
            typedef _Alloc allocator_type;
            static const size_type npos;
            basic_string(const _CharT* __s, size_type __n);
            size_type length() const;
            size_type max_size() const;
            size_type capacity() const;
            void reserve(size_type __res_arg);
            %extend { 
                void shrink_to_fit() { 
                    %#if __cplusplus >= 202002L
                    self->shrink_to_fit();
                    %#else
                    self->reserve();
                    %#endif
                }
            }
            basic_string& append(const basic_string& __str);
            basic_string& append(const basic_string& __str, size_type __pos, size_type __n);
            basic_string& append(size_type __n, _CharT __c);
            basic_string& assign(const basic_string& __str, size_type __pos, size_type __n);
            basic_string& assign(const _CharT* __s, size_type __n);
            basic_string& insert(size_type __pos1, const basic_string& __str);
            basic_string& insert(size_type __pos1, const basic_string& __str, 
                size_type __pos2, size_type __n);
            basic_string& insert(size_type __pos, const _CharT* __s, size_type __n);
            basic_string& insert(size_type __pos, size_type __n, _CharT __c);
            basic_string& erase(size_type __pos = 0, size_type __n = npos);
            basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str, 
                size_type __pos2, size_type __n2);
            basic_string& replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c);
            size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const;
            const _CharT* c_str() const;
            size_type find(const basic_string& __str, size_type __pos = 0) const;
            size_type find(_CharT __c, size_type __pos = 0) const;
            size_type rfind(const basic_string& __str, size_type __pos = npos) const;
            size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const;
            size_type rfind(_CharT __c, size_type __pos = npos) const;
            size_type find_first_of(const basic_string& __str, size_type __pos = 0) const;
            size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const;
            size_type find_first_of(_CharT __c, size_type __pos = 0) const;
            size_type find_last_of(const basic_string& __str, size_type __pos = npos) const;
            size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const;
            size_type find_last_of(_CharT __c, size_type __pos = npos) const;
            size_type find_first_not_of(const basic_string& __str, size_type __pos = 0) const;
            size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const;
            size_type find_first_not_of(_CharT __c, size_type __pos = 0) const;
            size_type find_last_not_of(const basic_string& __str, size_type __pos = npos) const;
            size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const;
            size_type find_last_not_of(_CharT __c, size_type __pos = npos) const;
            basic_string substr(size_type __pos = 0, size_type __n = npos) const;
            int compare(const basic_string& __str) const;
            int compare(size_type __pos, size_type __n, const basic_string& __str) const;
            int compare(size_type __pos1, size_type __n1, const basic_string& __str, 
                size_type __pos2, size_type __n2) const;
            %ignore pop_back();
            %ignore front() const;
            %ignore back() const;
            %ignore basic_string(size_type n);
            %ignore pop();
    };
}